package com.powernode.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.powernode.constant.BusinessEnum;
import com.powernode.domain.MemberAddr;
import com.powernode.domain.OrderItem;
import com.powernode.ex.handler.BusinessException;
import com.powernode.feign.OrderMemberFeign;
import com.powernode.mapper.OrderItemMapper;
import com.powernode.model.Result;
import com.powernode.utils.AuthUtils;
import com.powernode.vo.OrderStatusCount;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.Order;
import com.powernode.mapper.OrderMapper;
import com.powernode.service.OrderService;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderMemberFeign orderMemberFeign;

    @Override
    public Page<Order> queryOrderPage(Page<Order> page, String orderNumber, Integer status, Date startTime, Date endTime) {
        //多条件分页查询订单列表
        page = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
                .eq(ObjectUtil.isNotNull(status), Order::getStatus, status)
                .between(ObjectUtil.isAllNotEmpty(startTime, endTime), Order::getCreateTime, startTime, endTime)
                .eq(StringUtils.hasText(orderNumber), Order::getOrderNumber, orderNumber)
                .orderByDesc(Order::getCreateTime));
        //从订单分页对象中获取订单记录
        List<Order> orderList = page.getRecords();
        //判断是否有值
        if (CollectionUtils.isEmpty(orderList) || orderList.size() == 0) {
            return page;
        }
        //从订单记录集合中获取订单编号集合
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        //根据订单编号查询所有订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList));
        //循环遍历订单记录集合
        orderList.forEach(order -> {
            //从订单商品条目对象集合中过滤出当前订单记录的编号一致的订单商品条目对象集合
            List<OrderItem> itemList = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                    .collect(Collectors.toList());
            order.setOrderItems(itemList);
        });
        return page;
    }


    /**
     * 根据订单编号查询订单详情
     *
     * @param orderNumber
     * @return
     */
    @Override
    public Order queryOrderDetailByOrderNumber(Long orderNumber) {
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber));

        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, orderNumber));
        order.setOrderItems(orderItemList);
        Long addrOrderId = order.getAddrOrderId();
        //远程调用:根据收货地址标识查询地址详情
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(addrOrderId);
        //判断结果
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException("远程接口调用失败: 根据收货地址标识查询收货地址信息");
        }
        //获取数据
        MemberAddr memberAddr = result.getData();
        order.setUserAddrOrder(memberAddr);

        //远程接口调用: 根据会员openid查询会员名称
        Result<String> result1 = orderMemberFeign.getNickNameByOpenId(order.getOpenId());
        //判断结果
        if (result1.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException("远程接口调用失败: 根据会员openid查询会员名称");
        }
        //获取数据
        String nickName = result1.getData();
        order.setNikeName(nickName);
        return order;
    }

    /**
     * 查询会员订单各状态数据
     *
     * @return
     */
    @Override
    public OrderStatusCount queryMemberOrderStatusCount() {
        //获取会员openid
        String openId = AuthUtils.getMemberOpenId();
        //根据会员openid查询待支付订单数量
        Long unPay = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 1));

        //根据会员openid查询待发货订单数量
        Long payed = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 2));

        //根据会员openid查询待收货订单数量
        Long consignment = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 3));
        return OrderStatusCount.builder()
                .unPay(unPay).payed(payed).consignment(consignment)
                .build();
    }

    /**
     * 查询会员订单分页列表
     *
     * @param current
     * @param size
     * @param status
     * @return
     */
    @Override
    public Page<Order> queryMemberOrderPage(Long current, Long size, Long status) {
        //获取会员openid
        String openId = AuthUtils.getMemberOpenId();
        //创建订单分页对象
        Page<Order> page = new Page<>(current, size);
        //分页查询会员订单列表
        page = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(0 != status, Order::getStatus, status)
                .eq(Order::getDeleteStatus, 0)
                .orderByDesc(Order::getCreateTime));

        //从订单分页对象中获取订单记录集合
        List<Order> orderList = page.getRecords();
        //判断是否有值
        if (CollectionUtils.isEmpty(orderList) || orderList.size() == 0) {
            return page;
        }
        //从订单集合中获取订单编号集合
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        //根据订单编号查询所有订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList));
        //循环遍历订单记录集合
        orderList.forEach(order -> {
            //从订单商品条目对象集合中过滤出当前订单记录的编号一致的订单商品条目对象集合
            List<OrderItem> itemList = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                    .collect(Collectors.toList());
            order.setOrderItemDtos(itemList);
        });
        return page;
    }


    /**
     * 根据订单编号查询会员订单详情
     *
     * @param orderNumber
     * @return
     */
    @Override
    public Order queryMemberOrderDetailByOrderNumber(String orderNumber) {
        //根据订单编号查询订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber));
        //判断订单是否存在
        if (ObjectUtil.isNull(order)) {
            throw new BusinessException("订单有误");
        }
        //远程调用: 查询订单收货地址对象
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(order.getAddrOrderId());
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("查询订单收货地址失败");
        }
        //获取订单收货地址信息
        MemberAddr memberAddr = result.getData();
        order.setUserAddrDto(memberAddr);
        //根据订单编号查询订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, orderNumber));
        order.setOrderItemDtos(orderItemList);
        return order;
    }


    /**
     * 确认收货
     *
     * @param orderNumber
     * @return
     */
    @Override
    public Boolean receiptMemberOrder(String orderNumber) {
        //创建订单对象
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setFinallyTime(new Date());
        order.setStatus(5);
        return orderMapper.update(order, new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)) > 0;
    }

    /**
     * 删除订单
     *
     * @param orderNumber
     * @return
     */
    @Override
    public Boolean removeMemberOrderByOrderNumber(String orderNumber) {
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setDeleteStatus(1);
        return orderMapper.update(order, new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)) > 0;
    }
}
